package com.example.app;

import android.content.Context;
import android.util.Log;

import com.example.app.observer.MyObserver;
import com.example.app.observer.MySubjectImpl;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by ZLW on 2017/7/1.
 */

public class ProxyUtils implements MyObserver {


    private static final String TAG = "ProxyUtils";
    private Context mContext;

    public void hook(Context context) {
        this.mContext = context;
        MySubjectImpl.getInstance().registerObserver(this);

    }

    /**
     * 当Activyt被创建的时候
     * @param task
     */
    @Override
    public void noticyObserver(MyAsyncTask task) {
        //找到老的接口对象
        try {
            Class<?> aClass = Class.forName("com.example.app.MyAsyncTask");
            Field mListener = aClass.getDeclaredField("mListener");
            mListener.setAccessible(true);

            //老的监听器
            final Object o = mListener.get(task);

            print(o);

            //////////////////////////////////////////////////
//            //创建一个新的监听器,这是重新把对象覆盖了
//            MyAsyncTask.OnCompleteListener newListener = new MyAsyncTask.OnCompleteListener() {
//                @Override
//                public void onComplete(String result) {
//                    Log.e("我是新的监听器", result);
//                    ((MyAsyncTask.OnCompleteListener) o).onComplete(result.toUpperCase());
//                }
//            };

//            mListener.set(task,newListener);
            //////////////////////////////////////////////////

            //这种方式是动态代理的方式
            Class<?> aClass1 = Class.forName("com.example.app.i.OnCompleteListener");
//            //创建动态代理
            Object proxyInstance = Proxy.newProxyInstance(
                    mContext.getClassLoader(),
                    new Class[]{aClass1},
                    new MyInvocationHandler(o));
            mListener.set(task,proxyInstance);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private class MyInvocationHandler implements InvocationHandler {

        private  Object oldListener;
        public MyInvocationHandler(Object o) {
            this.oldListener = o;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Log.e(TAG, "invoke: " + "拦截到了\n" + method.getName() + "\n" +
                    "args = " + args.toString());

            if ("onComplete".equals(method.getName())) {
                for (int i = 0; i < args.length; i++) {
                    if (args[i] instanceof String) {
                        String s = ((String) args[i]).toUpperCase();
                        args[i] = s;
                        break;
                    }
                }
            }

            return method.invoke(oldListener,args);
        }

    }


    private void print(Object o) {
        if (o != null) {
            Log.e(TAG, "hook: " + o.toString());

        }else {
            Log.e(TAG, "hook: " + "监听器为null" );
        }
    }
}
